<!DOCTYPE html>
<html>
<head>
    <title>立体仓储系统-三维视图</title>
    <meta charset="UTF-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<link rel="stylesheet" href="css/all.min.css">
	<link rel="stylesheet" href="css/index.css">
    <script src="js/jquery-3.7.1.min.js"></script>
	<script src="js/index.js"></script>
	<script src="js/data-wms.js"></script>
    <style>		
		
        .progress-bar {
            flex: 1;
            height: 20px;
            background: rgba(255, 255, 255, 0.6);
            border-radius: 7px;
            overflow: hidden;
            position: relative;
            max-width: 400px;
        }
        .progress-fill {
            height: 100%;
            background: #2a9d8f;
            width: 20%;
            border-radius: 7px;
            transition: width 0.5s ease;
            position: relative;
        }
        .progress-fill-80 {
            background: #e7b151;
        }
        .progress-fill-100 {
            background: #e76f51;
        }
        .progress-text {
            position: absolute;
            right: 10px;
            top: 50%;
            transform: translateY(-50%);
            color: #e6e6e6;
            font-size: 14px;
        }
		
        #info {
            position: absolute;
            top: 60px;
            left: 10px;
            color: #90e0ef;
            font-family: Arial;
            background: rgba(0,0,0,0.7);
            padding: 10px;
            border-radius: 5px;
            z-index: 1;
        }
        #toggleAnimation {
            position: absolute;
            bottom: 10px;
            left: 10px;
            z-index: 100;
            color: white;
            background: rgba(0, 0, 0, 0.5);
            padding: 5px 10px;
            border-radius: 3px;
            font-size: 12px;
        }
        #controls {
            position: absolute;
            top: 60px;
            right: 10px;
            background: rgba(0,0,0,0.7);
            padding: 10px;
            border-radius: 5px;
            z-index: 1;
            color: white;
            font-family: Arial;
            display: flex;
            flex-direction: row;
            gap: 20px;
        }
        #controls h3 {
            margin: 5px 0;
            text-align: center;
        }
        #controls h4 {
            margin: 5px 0;
            text-align: center;
        }
        #controls label {
            display: block;
            margin: 3px 0;
            cursor: pointer;
            white-space: nowrap;
        }
        .filter-column {
            display: flex;
            flex-direction: column;
        }
        .filter-column div{
            display: none;
        }
		.toggle-icon {
		  position: absolute;
		  left: 50%;
		  bottom: 2px;
		  transform: translateX(-50%);
		  cursor: pointer;
		  font-size: 10px;
		  width: 20px;
		  text-align: center;
		}
		.toggle-icon:hover {
		  color: #90e0ef;
		}
    </style>
</head>
<body>
	<!-- 导航栏 -->
    <div id="floating-nav">
        <div class="nav-collapsed"></div>
        <div class="nav-content">
            <div class="nav-icon nav-icon-active" data-tooltip="库存监控" data-url="wms-3d.html">
                <i class="fas fa-chart-bar"></i>
            </div>
            <div class="nav-icon" data-tooltip="热力图" data-url="heatmap-3d.html">
                <i class="fas fa-braille"></i>
            </div>
            <div class="nav-icon" data-tooltip="数据同步" data-url="data-sync.html">
                <i class="fas fa-exchange"></i>
            </div>
        </div>
    </div>
	
	<div class="title">
	<div class="summary-container">
        <div class="storage-selector">
            <select id="storageSelect">
                <option value="D">国内存储区</option>
                <option value="I">国际存储区</option>
            </select>
        </div>
        <div class="progress-bar">
            <div class="progress-fill" style="width: 20%">
                <div class="progress-text">20%</div>
            </div>
        </div>
        <div class="summary-stats"></div>
	
		<div class="view-control">
			<a href="wms-card.html"><i title="卡片视图" class="fa fa-image"></i></a>
			<a href="wms-2d.html"><i title="侧/俯视图" class="fa-solid fa-list"></i></a>
			<i title="三维视图" class="fa-solid fa-cube active" click="javascript"></i>
		</div>
    </div>
	<div class="screen-control" id="fullscreen-component">
		<i class="fas fa-expand fullscreen-toggle" title="进入全屏"></i>
	</div>
	</div>

    <div id="info">点击库位查看详细信息</div>
    <button id="toggleAnimation">开始旋转</button>
    <div id="controls">
        <div class="filter-column">
            <h4>货架排</h4>
            <div id="rowFilters">
            </div>
        </div>
        <div class="filter-column">
            <h4>货架层</h4>
            <div id="levelFilters">
            </div>
        </div>
		<div class="toggle-icon">▼</div>
    </div>
    <script src="ThreeJs/js/three.js"></script>
    <script src="ThreeJs/js/OrbitControls.js"></script>
    
    <script>
		
        let scene, camera, renderer, controls;
        let composer;
        let font;
        
        let warehouseGroup = new THREE.Group();
        let isAnimating = false;
        let highlightedCell = null;
        let selectedCell = null;
        
        const shelfUnits = []; 	// 存储所有货架单元
        const shelfGroups = []; // 存储所有货架组
        const shelfRows = []; 	// 存储每排货架的可见状态
        const shelfLevels = []; // 存储每层货架的可见状态

        const shelfConfig = {
			racks: [20,3,10],  		// 库位量(列,层,排)(x,y,z)
            cellSize: [0.7,0.6,1],  	// 单个库位的大小(宽,高,深)(长,高,宽)(x,y,z)
            rowSpacing:1,		// 货架间距(排间z) 每2排拉开距离
            cellPadding: 0.02 	// 库位间隔(x,z)
        };
		const rackHeight = shelfConfig.racks[1]*shelfConfig.cellSize[1];
		const rackLength = shelfConfig.racks[0]*shelfConfig.cellSize[0];
		
		const colorConfig ={
			highlight:0x66ffff	//高亮颜色
		}

        function init() {
            // 初始化可见状态数组
            for (let i = 0; i < shelfConfig.racks[2]; i++) {
                shelfRows.push(true); 	// 默认所有排都可见
            }
            for (let i = 0; i < shelfConfig.racks[1]; i++) {
                shelfLevels.push(true); // 默认所有层都可见
            }

            // 场景
            scene = new THREE.Scene();
            scene.background = new THREE.Color(0x16213e);

            // 相机
            camera = new THREE.PerspectiveCamera(35, window.innerWidth/window.innerHeight, 0.1, 1000);
            camera.position.set(15, 20, 25);

            // 渲染器
            renderer = new THREE.WebGLRenderer({ antialias: true });
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(renderer.domElement);

            // 灯光
            setupLighting();

            // 控制器
            controls = new THREE.OrbitControls(camera, renderer.domElement);
            controls.enableDamping = true;
            
            // 货架容器组
            warehouseGroup = new THREE.Group();
            scene.add(warehouseGroup);

            // 货架
            createShelfRow(shelfConfig.racks[2]);
            
            // 过滤控制UI
            createFilterControls();

			
            // 事件监听
            window.addEventListener('resize', onWindowResize, false);
            window.addEventListener('click', onMouseClick, false);
            renderer.domElement.addEventListener('mousemove', onMouseMove);
            document.getElementById('toggleAnimation').addEventListener('click', toggleAnimation);
            
            animate();
        }
		
		let frameVisible =true;
        function createFilterControls() {
			$('.toggle-icon').click(function() {
				$('.filter-column div').slideToggle(300, function() {
				  $('.toggle-icon').text($('.filter-column div').is(':visible') ? "▲" : "▼");
				});
			});
            const rowFiltersDiv = document.getElementById('rowFilters');
            const levelFiltersDiv = document.getElementById('levelFilters');
            
            // 排数过滤器(z)
            for (let i = shelfConfig.racks[2]-1; i >=0; i--) {
                const checkbox = document.createElement('input');
                checkbox.type = 'checkbox';
                checkbox.id = `row-${i}`;
                checkbox.checked = true;
                checkbox.addEventListener('change', () => {
                    shelfRows[i] = checkbox.checked;
                    updateShelfVisibility();
                });
                
                const label = document.createElement('label');
                label.htmlFor = `row-${i}`;
                label.appendChild(checkbox);
                label.appendChild(document.createTextNode(` ${i+1}排`));
                
                rowFiltersDiv.appendChild(label);
            }
			// 顶板
            const chk1 = document.createElement('input');
            chk1.type = 'checkbox';
            chk1.id = `level-chk1`;
            chk1.checked = true;
            chk1.addEventListener('change', () => {
                frameVisible = chk1.checked;
                updateShelfVisibility();
            });
            const lbl = document.createElement('label');
            lbl.htmlFor = `level-chk1`;
            lbl.appendChild(chk1);
            lbl.appendChild(document.createTextNode(`顶板`));
            levelFiltersDiv.appendChild(lbl);
            
            // 层数过滤器(y)
            for (let i = shelfConfig.racks[1]-1; i >= 0; i--) {
                const checkbox = document.createElement('input');
                checkbox.type = 'checkbox';
                checkbox.id = `level-${i}`;
                checkbox.checked = true;
                checkbox.addEventListener('change', () => {
                    shelfLevels[i] = checkbox.checked;
                    updateShelfVisibility();
                });
                
                const label = document.createElement('label');
                label.htmlFor = `level-${i}`;
                label.appendChild(checkbox);
                label.appendChild(document.createTextNode(` ${i+1}层`));
                
                levelFiltersDiv.appendChild(label);
            }
        }

        function updateShelfVisibility() {
            shelfGroups.forEach((group, rowIndex) => {
                // 检查该排是否可见
                const rowVisible = shelfRows[rowIndex];
                
                // 遍历该排的所有库位
                group.children.forEach(child => {
					//console.log(child.name);
                    if (child.userData && child.name === "shelf" && child.userData.coordY === shelfConfig.racks[1]+1) {
						// 顶部楼板
						child.visible = rowVisible && frameVisible;
                    } else if (child.userData && child.userData.coordY !== undefined) {
						//console.log(child.name);
						//console.log(child.userData.coordY);
                        // 检查该库位所在层是否可见
                        const levelVisible = shelfLevels[child.userData.coordY - 1];
						child.visible = rowVisible && levelVisible;
						//if(child.name==="cell") child.visible = rowVisible && levelVisible;
						//else if(child.name==="shelf") child.visible = levelVisible;
                    } else {
                        // 框架部分始终可见
                        child.visible = rowVisible;
                    }
                });
            });
        }

        function setupLighting() {
            const ambientLight = new THREE.AmbientLight(0x404040);
            scene.add(ambientLight);
            
            const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
            directionalLight.position.set(10, 20, 10);
            directionalLight.castShadow = true;
            directionalLight.shadow.mapSize.width = 1024;
            directionalLight.shadow.mapSize.height = 1024;
            scene.add(directionalLight);
            // 平行光2
            const directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.5);
            directionalLight2.position.set(-10, 20, -10);
            scene.add(directionalLight2);
        }

        function createShelfRow(z) {
			let rowSpacing = 0;
            for(let i = 0; i < z; i++) {
                const shelfGroup = createSingleShelf(i);
				if(i%2===0) rowSpacing +=shelfConfig.rowSpacing*2; //双排2倍间距
				else rowSpacing +=shelfConfig.rowSpacing;
				shelfGroup.position.z = -i * shelfConfig.cellSize[2] - rowSpacing;
                //shelfGroup.position.z = -i * (shelfConfig.cellSize[2] + shelfConfig.rowSpacing);
                warehouseGroup.add(shelfGroup);
                shelfGroups.push(shelfGroup); // 保存货架组
            }
        }

        function createSingleShelf(z) {
            const shelfGroup = new THREE.Group();
            // 货架框架
            createFrame(shelfGroup,z);
            // 库位
            createShelfCells(shelfGroup,z);

            return shelfGroup;
        }

        function createFrame(group,z) {
            const frameMaterial = new THREE.MeshPhongMaterial({ 
                color: 0x666666,
                opacity: 0.3,
            });
            // 垂直支柱
            const pillarGeometry = new THREE.BoxGeometry(0.1,rackHeight , 0.1);
            const pillarPositions = [
                [-rackLength/2-0.05, 0, -shelfConfig.cellSize[2]/2],
                [ rackLength/2+0.05, 0, -shelfConfig.cellSize[2]/2],
                [-rackLength/2-0.05, 0,  shelfConfig.cellSize[2]/2],
                [ rackLength/2+0.05, 0,  shelfConfig.cellSize[2]/2]
            ];
            
            pillarPositions.forEach(pos => {
                const pillar = new THREE.Mesh(pillarGeometry, frameMaterial);
                pillar.position.set(pos[0], rackHeight/2, pos[2]);
                group.add(pillar);
            });
            // 水平横梁
            //const beamGeometry = new THREE.BoxGeometry(shelfConfig.racks[0], 0.05, 0.05);
            //const topBeam = new THREE.Mesh(beamGeometry, frameMaterial);
            //topBeam.position.y = shelfConfig.racks[1];
            //group.add(topBeam);
            
            // 层板
            const levelHeight = shelfConfig.cellSize[1];
            const shelfGeometry = new THREE.BoxGeometry(rackLength, 0.02, shelfConfig.cellSize[2]);
            for(let i = 0; i <= shelfConfig.racks[1]; i++) {
                const shelf = new THREE.Mesh(shelfGeometry, frameMaterial);
                shelf.position.y = levelHeight * i;
				shelf.userData = {
					coordY: i+1
				};
				shelf.name="shelf";
                group.add(shelf);
            }
			
			// 货架编号
			createChannelText(group,z);
			createRowText(group,z);
        }

		function createChannelText(group,z) {
			if(z%2===1) return;
			// ⚪在货架两端添加通道标签
			const loader = new THREE.TextureLoader();
			const canvas = document.createElement('canvas');
			canvas.width = 128;
			canvas.height = 128;
			const context = canvas.getContext('2d');
			// 绘制文本到canvas
			context.fillStyle = '#90e0ef';
			context.font = 'Bold 60px Arial';
			context.textAlign = 'center';
			context.textBaseline = 'middle';
			context.fillText((z/2+1).toString(), 64, 64);
			// 创建纹理材质
			const texture = new THREE.CanvasTexture(canvas);
			const labelMaterial = new THREE.SpriteMaterial({
				map: texture,
				transparent: true,
				opacity: 1
			});
			// 创建标签
			const createLabel = (xPos) => {
				const label = new THREE.Sprite(labelMaterial);
				label.scale.set(2, 2, 1);
				label.position.set(
					xPos,
					//rackHeight/2,-shelfConfig.cellSize[1]/2 + 0.5*shelfConfig.cellSize[1] //中间
					//rackHeight + 0.5, 0//顶部
					0.5, -1
				);
				group.add(label);
			};
			createLabel(-rackLength/2 - 0.5);
			createLabel( rackLength/2 + 0.5);
        }		
		function createRowText(group,z) {
			
			// ⚪在最上层层板面上添加编号
			// 创建编号
            const canvas = document.createElement('canvas');
            const context = canvas.getContext('2d');
            canvas.width = 256;
            canvas.height= 256;
            // 绘制背景
            context.fillStyle = '#CCCCCC';
            context.fillRect(0, 0, canvas.width, canvas.height);
            // 绘制边框
            //context.strokeStyle = '#333333';
            //context.lineWidth = 8;
            //context.strokeRect(10, 10, canvas.width - 20, canvas.height - 20);
            // 绘制数字
            context.font = 'bold 160px Arial';
            context.textAlign = 'center';
            context.textBaseline = 'middle';
            context.fillStyle = '#000000';
            context.fillText((z+1).toString(), canvas.width / 2, canvas.height / 2);
            // 创建纹理
            const texture = new THREE.CanvasTexture(canvas);
            texture.minFilter = THREE.LinearFilter;
            texture.magFilter = THREE.LinearFilter;
            // 创建编号平面
            const labelGeometry = new THREE.PlaneGeometry(0.8, 0.8);
            const labelMaterial = new THREE.MeshBasicMaterial({map: texture});
			
			const createLabel = (xPos,zRot) => {
				const label = new THREE.Mesh(labelGeometry, labelMaterial);
				label.position.set(xPos, rackHeight + 0.03, 0); 
				label.rotation.x = -Math.PI / 2; 
				label.rotation.z = -Math.PI / zRot; 
				group.add(label);
			};
			createLabel(-rackLength/2 + .5, 2);
			createLabel( rackLength/2 - .5,-2);
        }

        function createShelfCells(group,z) {
            const cellWidth = shelfConfig.cellSize[0];
            const cellHeight= shelfConfig.cellSize[1];
            const cellDepth = shelfConfig.cellSize[2];
			const cubeWidth  = cellWidth  - shelfConfig.cellPadding;
			const cubeHeight = cellHeight - shelfConfig.cellPadding;

            for(let y = 0; y < shelfConfig.racks[1]; y++) {
                for(let x = 0; x < shelfConfig.racks[0]; x++) {
					let line,pallet;
					var cellGeometry = new THREE.BoxGeometry( cubeWidth, cubeHeight, cellDepth );
					var yPos = cellHeight/2 + y * cellHeight;
					var goodsNo="";
					const w=warehouses.find(w => `${w.coordW[0]}-${w.coordW[1]}-${w.coordW[2]}` === `${x+1}-${y+1}-${z+1}`);
					const spaceNo = w ? w.spaceNo : "";
					const goods = goodsData.find(g => g.spaceNo === spaceNo);
					if(goods){
						//有货物
						goodsNo=goods.goodsNo;
						// 托盘
						const palletThickness = 0.05; // 托盘厚度
						const palletGeometry = new THREE.BoxGeometry(cubeWidth * 0.85, palletThickness, cellDepth * 0.85);
						const palletMaterial = new THREE.MeshBasicMaterial({ color: 0xe7e750 });
						pallet = new THREE.Mesh(palletGeometry, palletMaterial);
						// 托盘位置
						pallet.position.y = palletThickness -cellHeight/2;
						
						//是行李
						if(goods.goodsType ==="bag"){
							// 2行李箱
							var suitcaseColor=new THREE.Color(0x99ffcc);
							if(goods.state ==="storing") suitcaseColor=new THREE.Color(0x90e0ef);
							if(goods.state ==="stored" ) suitcaseColor=new THREE.Color(0x0099ff);
							const suitcaseHeight = cellHeight * 0.3;
							const suitcaseGeometry = new THREE.BoxGeometry(cubeWidth * 0.4, suitcaseHeight, cellDepth * 0.4);
							const suitcaseMaterial = new THREE.MeshBasicMaterial({ color: suitcaseColor });
							const suitcase = new THREE.Mesh(suitcaseGeometry, suitcaseMaterial);
							// 2行李箱位置
							suitcase.position.y = suitcaseHeight / 2;
							
							// 2.1行李箱提手
							//const handleGeometry = new THREE.BoxGeometry(cubeWidth * 0.4 * 0.6, suitcaseHeight * 0.5, cubeWidth * 0.4 * 0.1);
							//const handleMaterial = new THREE.MeshBasicMaterial({ color: 0xDAA520 });
							//const handle = new THREE.Mesh(handleGeometry, handleMaterial);
							// 2.1提手位置
							//handle.position.y = palletThickness + suitcaseHeight/2;
							//handle.position.z = cubeWidth * 0.4 * 0.3; // 偏移提手使其更自然
							// 2.1提手添加到行李箱
							//suitcase.add(handle);
							
							// 2行李箱添加到托盘
							pallet.add(suitcase);
						}
						
					}else{
						//无货物
						if(w){
							//有库位
						}else{
							//无库位
							continue;
						}
					}
					
                    const material = new THREE.MeshPhongMaterial({ color: 0xcccccc, transparent: true, opacity: 0.01 });
					//console.log(cellGeometry);
                    const cell = new THREE.Mesh(cellGeometry, material);
                    // 位置
                    const xPos = -rackLength/2 + cellWidth/2 + x * cellWidth;
                    //const yPos = cellHeight/2 + y * cellHeight;
                    const zPos = 0;
                    cell.position.set(xPos, yPos, zPos);
					
					// 边框
					if(w){
						//有库位
						let color;
						const ws = warehouseStates.find(w => w.spaceNo === spaceNo);
						if(ws){
							//库位状态
							if(ws.deviceState ==="Normal"){
								color=new THREE.Color(0x666666); //0x00ff99
							}else{
								color=new THREE.Color(0xff6f51);
							}
						}else{
							// 未知状态
							color=new THREE.Color(0xcccccc);
						}
						line = new THREE.LineSegments(
							new THREE.EdgesGeometry(cellGeometry),
							new THREE.LineBasicMaterial({ color: color, linewidth: 1 })
						);
						//console.log(line);
						cell.add(line);
					}
					
					// 托盘添加到货位
					if(pallet) cell.add(pallet);
					
					// 文字
					if(goodsNo!==""){
					//	const canvas = document.createElement('canvas');
					//	canvas.width = 64;
					//	canvas.height = 32;
					//	const context = canvas.getContext('2d');
					//	context.fillStyle = 'rgba(0, 0, 0, 0.5)';
					//	context.fillRect(0, 0, canvas.width, canvas.height);
					//	context.font = 'Bold 20px Arial';
					//	context.fillStyle = 'white';
					//	context.textAlign = 'center';
					//	context.textBaseline = 'middle';
					//	context.fillText(goodsNo.slice(-6), canvas.width/2, canvas.height/2);
					//							
					//	const texture = new THREE.CanvasTexture(canvas);
					//	const spriteMaterial = new THREE.SpriteMaterial({ 
					//		map: texture,
					//		transparent: true//,
					//		//depthTest: false
					//	});
					//	const sprite = new THREE.Sprite(spriteMaterial);
					//	sprite.scale.set(0.5, 0.25, 1);
					//	sprite.position.set(0, 0, 0.51);
					//	sprite.rotation.y = Math.PI / 2;
					//	sprite.rotation.x = Math.PI / 2;
					//	//sprite.position.z = -shelfConfig.cellSize[1]/2 + 0.5*shelfConfig.cellSize[1];
					//	cell.add(sprite);
					}
					
					//console.log(cell);
					// 自定义数据
                    cell.userData = {
                        coordX: x+1,
                        coordY: y+1,
                        coordZ: z+1,
                        coordinate: `${x+1}-${y+1}-${z+1}`,
                        spaceNo: spaceNo,
						originalOpacity:0.01,
                        originalColor: material.color.clone(),
						line:{
							originalColor: line.material.color.clone(),
							material:line.material
						},
						pallet:pallet,
                        status: line.material.color.getHex()
                    };
					cell.name="cell";
                    shelfUnits.push(cell);
                    group.add(cell);
                }
            }
        }
		
		// 鼠标移动事件
		function onMouseMove(event) {
			const intersects = getRaycasterIntersects(event);
			const cell = intersects.length > 0 ? intersects[0].object : null;
			
			updateHighlight(cell);
			showCellInfo(cell || selectedCell);
		}

		// 鼠标点击事件
		function onMouseClick(event) {
			const intersects = getRaycasterIntersects(event);
			const cell = intersects.length > 0 ? intersects[0].object : null;
			
			updateSelection(cell);
			showCellInfo(selectedCell);
		}
		
		function getRaycasterIntersects(event) {
			const mouse = new THREE.Vector2(
				(event.clientX / window.innerWidth) * 2 - 1,
				-(event.clientY / window.innerHeight) * 2 + 1
			);

			const raycaster = new THREE.Raycaster();
			raycaster.setFromCamera(mouse, camera);
			
			const visibleShelfUnits = shelfUnits.filter(unit => unit.visible);
			return raycaster.intersectObjects(visibleShelfUnits);
		}
		
		// 更新高亮单元格
		function updateHighlight(cell) {
			if (highlightedCell && highlightedCell !== selectedCell) {
				highlightedCell.material.color.copy(highlightedCell.userData.originalColor);
				highlightedCell.material.opacity=highlightedCell.userData.originalOpacity;
				highlightedCell.userData.line.material.color.copy(highlightedCell.userData.line.originalColor);
			}
			
			if (cell && cell !== selectedCell) {
				highlightedCell = cell;
				highlightedCell.material.color.set(colorConfig.highlight);
				highlightedCell.material.opacity=0.3;
				highlightedCell.userData.line.material.color.set(colorConfig.highlight);
			} else {
				highlightedCell = null;
			}
		}
		// 更新选中单元格
		function updateSelection(cell) {
			if(cell == null) {
				return; //空白处
			}
			if (selectedCell) {
				selectedCell.material.color.copy(selectedCell.userData.originalColor);
				selectedCell.material.opacity=selectedCell.userData.originalOpacity;
				selectedCell.userData.line.material.color.copy(selectedCell.userData.line.originalColor);//已选择的复位
			}
			if (selectedCell === cell) {
				selectedCell = null; //取消选中
			} else {
				selectedCell = cell; //选中
				selectedCell.material.color.set(colorConfig.highlight);
				selectedCell.material.opacity=0.3;
				//selectedCell.material.needsUpdate = true;
				selectedCell.userData.line.material.color.set(colorConfig.highlight);
			}
		}
        function showCellInfo(cell) {
			const infoDiv = document.getElementById('info');
			if(cell){
				var status="";
				var spaceNo=cell.userData.spaceNo;
				const w = warehouses.find(item => item.spaceNo === spaceNo);
				if(w){
					//有库位
					const ws = warehouseStates.find(w => w.spaceNo === spaceNo);
					if(ws){
						if(ws.deviceState ==="Normal"){
							status="正常";
						}else{
							status="禁用";
						}
					}else{
						status="未知";
					}
				}else{
					status="无库位";
				}
				infoDiv.innerHTML = `
					库位坐标：${cell.userData.coordinate} (列-层-排)<br>
					库位状态：${status}<br>
				`;
				const goods = goodsData.find(g => g.spaceNo === spaceNo);
				if(goods){
					var goodsState=""+goods.state;
					if(goods.state ==="storing") goodsState="已分配";
					if(goods.state ==="stored") goodsState="已存储";
					
					var goodsType=""+goods.goodsType;
					if(goods.goodsType ==="pallet") goodsType="空框";
					if(goods.goodsType ==="bag") goodsType="行李";
					
					infoDiv.innerHTML += `<br>
						货物编号：${goods.goodsNo}<br>
						货物类型：${goodsType}<br>
						货物状态：${goodsState}
					`;
				}
			}else{
				infoDiv.innerHTML ="点击库位查看详细信息";
			}
        }

        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }
        
        function toggleAnimation() {
            isAnimating = !isAnimating;
            document.getElementById('toggleAnimation').textContent = 
                isAnimating ? '暂停旋转' : '开始旋转';
        }

        function animate() {
            requestAnimationFrame(animate);
            
            if (isAnimating) {
                warehouseGroup.rotation.y += 0.002;
            }
            
            controls.update();
            renderer.render(scene, camera);
        }

        init();
		
        $(function() {
			
			updateSumary();
		
        });
		
		
		function updateSumary(){
			const percentage = (summary.used / summary.total * 100).toFixed(0);
            $('.summary-stats').text(`${summary.used}/${summary.total}`);
            $('.progress-fill').css('width', `${percentage}%`);
            $('.progress-text').text(`${percentage}%`);
			if(percentage==100) $('.progress-fill').addClass("progress-fill-100");
			else if(percentage>=80 && percentage<100) $('.progress-fill').addClass("progress-fill-80");
		}
		
    </script>
</body>
</html>